#ifndef fsirenderer_h__
#define fsirenderer_h__
#include "colour.h"
#include "math/matrix44.h"
#include "batcher.h"

namespace gecko
{

// forward declare types
class IVertexBuffer;
class IIndexBuffer;
class Geometry;
class IShader;

// Abstract interface for renderer
class IRenderer
{
public:
    enum eRendermode
    {
		RM_POINT,
        RM_WIREFRAME,
        RM_SOLID
    };

    enum eRenderState
    {
        RS_LIGHTING,
        RS_ZBUFFER,
        RS_VERTEXCOLOUR,
        RS_ZWRITEENABLE,
        RS_POINTSPRITEENABLE,
    };

    enum eBlendMode
    {
        BM_ZERO,
        BM_ONE,
        BM_SRCCOLOR,
        BM_INVSRCCOLOR,
        BM_SRCALPHA,
        BM_INVSRCALPHA,
        BM_DESTALPHA,
        BM_INVDESTALPHA,
        BM_DESTCOLOR,
        BM_INVDESTCOLOR,
        BM_SRCALPHASAT
    };

    enum eCullMode
    {
        E_CULLMODE_NONE,
        E_CULLMODE_CW,
        E_CULLMODE_CCW
    };

	enum eBatchType
	{
		E_BATCHTYPE_SKYBOX,
		E_BATCHTYPE_GENERAL,
		E_BATCHTYPE_ALPHA,
        E_BATCHTYPE_INFINITY,
		E_BATCHTYPE_NUM
	};

	// Primitive types
	enum ePrimitiveType
	{
		PT_POINTLIST = 1,
		PT_LINELIST = 2,
		PT_LINESTRIP = 3,
		PT_TRIANGLELIST = 4,
		PT_TRIANGLESTRIP = 5,
		PT_TRIANGLEFAN = 6,
		PT_NUM
	};

    // Clear the renderer
    virtual void Clear() = 0;

    // Set the clear colour
    virtual void SetClearColour(const Colour& colour) = 0;

    // Start rendering the scene
    virtual bool BeginScene() = 0;

    // End rendering the scene
    virtual bool EndScene() = 0;

    // Swap buffers and display the scene
    virtual bool Present() = 0;

    // Cleanup after shutdown
    virtual bool Destroy() = 0;

	// Initialise the renderer
	virtual bool Initialise(int width, int height, int bpp, bool fullscreen) = 0;

	// setup camera
	virtual bool SetCamera(const Vector3f& from, const Vector3f& at, const Vector3f& up, float fov) = 0;
	
	// Set an orthographic (2D) projection matrix
	virtual bool SetOrthoProjection(int width, int height) = 0;

	// Set a perspective projection matrix
	virtual bool SetPerspectiveProjection(float fov, int width, int height, double nearClip, double farClip) = 0;

	// Create a vertex buffer.
	virtual IVertexBuffer* CreateVertexBuffer(unsigned int vertexCount, bool dynamic) = 0;

	// Create an index buffer.
	virtual IIndexBuffer* CreateIndexBuffer(unsigned int indexCount, bool dynamic) = 0;

	// Create a shader from a file
	virtual IShader* CreateShader(const char* filename, unsigned int numParameters) = 0;

	// set the global rendermode
	virtual void SetRenderMode(eRendermode renderMode) = 0;

	void AddBatchedGeometry(GeometryInstance* geometryInstance);
	void RenderBatchedGeometry();
	void RenderDebugLines(IEffect* shader);
	
private:
	GeometryBatchList m_GeometryBatchList;
	
protected:
	VertexCache m_VertexBatcher;
	Matrix44 m_viewMatrix;
	Matrix44 m_projectionMatrix;
};

}// namespace gecko

#endif // fsirenderer_h__